package com.zbkj.crmeb.payment.alipay.impl;

import com.alipay.easysdk.payment.app.models.AlipayTradeAppPayResponse;
import com.constants.Constants;
import com.constants.WeChatConstants;
import com.exception.CrmebException;
import com.zbkj.crmeb.payment.alipay.AlipayService;
import com.zbkj.crmeb.payment.vo.wechat.*;
import com.zbkj.crmeb.system.service.SystemConfigService;
import lombok.Data;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.alipay.easysdk.factory.Factory;
import com.alipay.easysdk.factory.Factory.Payment;
import com.alipay.easysdk.kernel.Config;
import com.alipay.easysdk.kernel.util.ResponseChecker;

import javax.annotation.PostConstruct;

@Slf4j
@Data
@Service
public class AlipayServiceImpl implements AlipayService {
    private CreateOrderRequestVo createOrderRequestVo;

    private PayParamsVo payParamsVo;

    @Autowired
    private SystemConfigService systemConfigService;

    @PostConstruct
    public void init() {
        // 1. 设置参数（全局只需设置一次）
        new Thread(new Runnable() {
            @SneakyThrows
            @Override
            public void run() {
                try {
                    Factory.setOptions(getOptions());
                } catch (Exception e) {
                    e.printStackTrace();
                    Thread.currentThread().sleep(60000);
                    run();
                }
            }
        }).start();

    }

    @Override
    public String create(PayParamsVo payParamsVo) {
        try {
            setPayParamsVo(payParamsVo);
            switch (payParamsVo.getFromType()) {
                case Constants.PAY_TYPE_ALI_APY_FROM: //h5
                    try {
                        // 2. 发起API调用
                        AlipayTradeAppPayResponse response = Payment.App().pay(payParamsVo.getTitle(), payParamsVo.getOrderNo(),
                                payParamsVo.getPrice() + "");

                        // 3. 处理响应或异常
                        if (ResponseChecker.success(response)) {
                            log.info("aliapy result is {}", response.getBody());
                            return response.getBody();
                        } else {
                            log.warn("调用失败，原因：{}" + response.body);
                            throw new RuntimeException("支付失败");
                        }
                    } catch (Exception e) {
                        System.err.println("调用遭遇异常，原因：" + e.getMessage());
                        throw new RuntimeException(e.getMessage(), e);
                    }
                default:
                    throw new CrmebException("系统不支持当前支付方式！");
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new CrmebException(e.getMessage());
        }
    }

    private Config getOptions() {
        Config config = new Config();
        config.protocol = "https";
        config.gatewayHost = "openapi.alipay.com";
        config.signType = "RSA2";

        config.appId = systemConfigService.getValueByKeyException(Constants.CONFIG_KEY_PAY_ALI_APY_APP_ID); //"<-- 请填写您的AppId，例如：2019091767145019 -->";
        // 为避免私钥随源码泄露，推荐从文件中读取私钥字符串而不是写入源码中
        config.merchantPrivateKey = systemConfigService.getValueByKeyException(Constants.CONFIG_KEY_PAY_ALI_APY_PRIVATE_KEY);//"<-- 请填写您的应用私钥，例如：MIIEvQIBADANB ... ... -->";

        //注：证书文件路径支持设置为文件系统中的路径或CLASS_PATH中的路径，优先从文件系统中加载，加载失败后会继续尝试从CLASS_PATH中加载
        String uploadPath = systemConfigService.getValueByKeyException(Constants.UPLOAD_ROOT_PATH_CONFIG_KEY);
        config.merchantCertPath = uploadPath + "/" + systemConfigService.getValueByKeyException(Constants.CONFIG_KEY_PAY_ALI_APY_appCertPath);//"<-- 请填写您的应用公钥证书文件路径，例如：/foo/appCertPublicKey_2019051064521003.crt -->";
        config.alipayCertPath = uploadPath + "/" + systemConfigService.getValueByKeyException(Constants.CONFIG_KEY_PAY_ALI_APY_alipayPublicCertPath);//"<-- 请填写您的支付宝公钥证书文件路径，例如：/foo/alipayCertPublicKey_RSA2.crt -->";
        config.alipayRootCertPath = uploadPath + "/" + systemConfigService.getValueByKeyException(Constants.CONFIG_KEY_PAY_ALI_APY_alipayRootCert);//"<-- 请填写您的支付宝根证书文件路径，例如：/foo/alipayRootCert.crt -->";

        //注：如果采用非证书模式，则无需赋值上面的三个证书路径，改为赋值如下的支付宝公钥字符串即可
        // config.alipayPublicKey = "<-- 请填写您的支付宝公钥，例如：MIIBIjANBg... -->";

        String apiDomain = systemConfigService.getValueByKeyException(Constants.CONFIG_KEY_API_URL);
        //可设置异步通知接收服务地址（可选）
        config.notifyUrl = apiDomain + WeChatConstants.PAY_NOTIFY_API_URI_ALI_PAY;//"<-- 请填写您的支付类接口异步通知接收服务地址，例如：https://www.test.com/callback -->";

        //可设置AES密钥，调用AES加解密相关接口时需要（可选）
//        config.encryptKey = "<-- 请填写您的AES密钥，例如：aa4BtZ4tspm2wnXLb1ThQA== -->";

        return config;
    }
}
